﻿using Lan.ServiceCore.Signalr;
using Lan.ServiceCore.WebScoket;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using RadarToLonLat;
using System.Collections.Concurrent;

namespace Lan.ServiceCore.TargetCollection
{
    public class TargetCollection
    {
        public enum TrackModeEnum
        {
            Auto,
            UserSelect,
            Manual
        }

        TrackModeEnum _trackMode;

        List<TargetPath> _targetPathList;       //防区当前报警目标列表

        public List<TargetPath> _targetPathListqt;       //防区当前报警目标列表
        int _pathId = 0;                        //在一个防区内，报警目标的唯一标志，非负整数
        int _pathIdSelected1 = -1;               //当前选定的跟踪目标标志，负数表示没有选中
        List<int> _pathIdSelected = new List<int>();               //当前选定的跟踪目标标志，负数表示没有选中
        DateTime _trackTime;                    //当前目标轮询的起始时间点，用于判断是否切换到下一个目标
        ConcurrentQueue<RadarTargetItem> _radarTargetQueue;    //雷达目标缓存队列
        //List<TargetFuse> _dictTargetFuse;
        private WDefenceArea _defenceArea;

        /// <summary>
        /// 目标轨迹列表
        /// </summary>
        public List<TargetPath> TargetList
        {
            get { return _targetPathList; }
            set { _targetPathList = value; }
        }

        public List<int> TargetIdSelected
        {
            get { return _pathIdSelected; }
            set
            {
                _trackTime = DateTime.Now;
                _pathIdSelected = value;
            }
        }

        public WDefenceArea DefenceArea
        {
            get { return _defenceArea; }
        }

        public TargetCollection(WDefenceArea defenceArea)
        {
            _trackTime = DateTime.MinValue;
            _trackMode = TrackModeEnum.Auto;
            _targetPathList = new List<TargetPath>();
            _targetPathListqt = new List<TargetPath>();
            _radarTargetQueue = new ConcurrentQueue<RadarTargetItem>();
            //_dictTargetFuse = new List<TargetFuse>();
            _defenceArea = defenceArea;
        }

        /// <summary>
        /// 清空目标列表
        /// </summary>
        internal void ClearTargets()
        {
            _targetPathList.Clear();
        }

        /// <summary>
        /// 从目标缓存队列中依次取目标，并更新目标列表
        /// </summary>
        /// <returns>新目标变为有效的次数统计，即有效目标增加数</returns>
        internal int CombineTargets()
        {
            List<TargetPath> pathsInDefenceArea = new List<TargetPath>(_targetPathList);

            pathsInDefenceArea = pathsInDefenceArea.Distinct().ToList();

            #region 目标处理
            //bool bAlarm = false;
            TargetPath tmpPath;
            RadarTargetItem tarItem;
            int availableTargetIncreasement = 0;
            int i;
            //遍历报警目标
            while (_radarTargetQueue.TryDequeue(out tarItem))
            {
                //TODO:sleep 异常

                //遍历防区目标列表
                for (i = pathsInDefenceArea.Count - 1; i >= 0; i--)
                {
                    tmpPath = pathsInDefenceArea[i];
                    if (tmpPath == null)
                    {
                        continue;
                    }
                    //如果找到同一个目标，更新
                    if (tmpPath.State < PathState.Lost && tmpPath.Equals(tarItem))   //只有是新建或有效状态的轨迹，才添加目标
                    {
                        tmpPath.IsEarlyWarning = tarItem.IsEarlyWarning;
                        tmpPath.Add(tarItem);
                        PathState newState;
                        if (tmpPath.State == PathState.New)      //如果这个轨迹处于新建状态，在添加目标后应检查轨迹是误报还是有效目标
                        {
                            newState = tmpPath.CheckState();          //检查轨迹状态
                            switch (newState)
                            {
                                case PathState.New:                             //没有达到过滤规则的超时时间，保持新建状态
                                    break;
                                case PathState.FalseAlarm:
                                    pathsInDefenceArea.RemoveAt(i);             //误报，移除
                                    break;
                                case PathState.Enable:
                                    tmpPath.State = PathState.Enable;
                                    availableTargetIncreasement++;
                                    break;
                            }
                        }
                        else
                            newState = PathState.Enable;

                        if (newState != PathState.FalseAlarm)
                            break;
                    }
                }
                //找不到同一个目标，添加到列表
                if (i < 0)
                {
                    TargetPath newPath = new TargetPath(tarItem, this);
                    newPath.IsEarlyWarning = tarItem.IsEarlyWarning;
                    pathsInDefenceArea.Add(newPath);
                }
            }
            #endregion

            List<TargetPath> main_list = new List<TargetPath>();

            main_list = pathsInDefenceArea;
            _targetPathList = main_list;
            return main_list.Count(path => (path.State == PathState.Enable && !path.IsEarlyWarning));
        }

        SendMS sms = null;

        /// <summary>
        /// 添加雷达的报警信息到目标缓存队列
        /// </summary>
        /// <param name="radar">发生报警的雷达</param>
        /// <returns>是否成功添加了目标</returns>
        internal bool AddTarget(WRadar radar)
        {
            DateTime now = DateTime.Now;
            bool isAdded = false;

            var serializerSettings = new JsonSerializerSettings
            {
                ContractResolver = new CamelCasePropertyNamesContractResolver(),
                // DateFormatString = timeFormatStr
            };

            foreach (var tar in radar.RadarTargets.Targets)
            {
                float x = tar.X;

                if (radar.InvertX)  //判断是否需要对X坐标反向
                    x = -x;

                RadarTargetItem tarItem = new RadarTargetItem(x, tar.Y, tar.SpeedY, tar.SpeedX, now, radar, tar.Type, tar.AxesX, tar.AxesY, tar.AzimuthAngle, tar.Id);

                tarItem.TargetId = (int)tar.Id;
                if (tarItem.Distance > DefenceArea.DefenceRadius)
                {
                    //距离超过防区半径的目标，剔除
                    continue;
                }

                float B_AzimuthAngle = radar.NorthDeviationAngle + 90;
                Double[] AlarmLonLat = LonLat.GetLonLat(double.Parse(radar.Latitude.ToString()), double.Parse(radar.Longitude.ToString()), double.Parse(B_AzimuthAngle.ToString()), tarItem.AxesX, tarItem.AxesY, tarItem.AzimuthAngle);

                sms = new SendMS { };
                sms.TargetId = (int)tar.Id;
                sms.Lat = AlarmLonLat[0];
                sms.Lng = AlarmLonLat[1];
                sms.TargetType = (int)tar.Type;

                string json = JsonConvert.SerializeObject(sms, Formatting.Indented, serializerSettings);
                Worker.AddTarget(json);

                _radarTargetQueue.Enqueue(tarItem);
                isAdded = true;
            }
            return isAdded;
        }

        /// <summary>
        /// 删除轨迹列表中已丢失或误报的轨迹
        /// </summary>
        internal void ClearLostTargets()
        {
            for (int i = _targetPathList.Count - 1; i >= 0; i--)
            {
                if (i >= _targetPathList.Count)
                {
                    break;
                }
                if (_targetPathList[i] == null)
                {
                    _targetPathList.RemoveAt(i);
                    break;
                }
                switch (_targetPathList[i].State)
                {
                    case PathState.New:
                        break;
                    case PathState.Enable:
                        break;
                    case PathState.Lost:
                    case PathState.FalseAlarm:
                        _targetPathList.RemoveAt(i);
                        break;
                }
            }
        }

        internal void CheckPathOvertime()
        {
            List<TargetPath> pathsInDefenceArea = new List<TargetPath>(_targetPathList);
            DateTime now = DateTime.Now;
            TargetPath tmpPath;

            for (int i = pathsInDefenceArea.Count - 1; i >= 0; i--)
            {
                tmpPath = pathsInDefenceArea[i];
                if (tmpPath != null)
                {
                    if (tmpPath.State == PathState.Enable && tmpPath.IsInvalid(now))
                    {
                        tmpPath.State = PathState.Lost;
                    }
                }
            }
        }

        internal void CheckPathOvertimeAlarm(DateTime AlarmBeginTime)
        {
            if (AlarmBeginTime < DateTime.Parse("2000-12-12 00:00:00"))
            {
                AlarmBeginTime = DateTime.Now;
            }

            List<TargetPath> ck_targetList = new List<TargetPath>(_targetPathList);
            // string str = "";
            foreach (TargetPath _TargetPath in ck_targetList)
            {
                if (_TargetPath.UpdateTime < AlarmBeginTime - TimeSpan.FromSeconds(4))
                {
                    //                            Console.WriteLine("清除轨迹");
                    // Log.Debug("清除轨迹1");
                    _targetPathList.Remove(_TargetPath);
                }
                else if (_TargetPath.UpdateTime < DateTime.Now - TimeSpan.FromSeconds(2))
                {
                    // Log.Debug("清除轨迹2");
                    _targetPathList.Remove(_TargetPath);
                }
            }
            // Log.Debug("清除目标打印" + str);
        }
    }
    public class SendMS
    {
        public int TargetId { get; set; }
        public double Lat { get; set; }
        public double Lng { get; set; }
        public int TargetType { get; set; }
    }
}
